package gui.geometry;

import gui.Paintbrush;

import java.awt.BasicStroke;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.geom.Line2D;

import model.NetworkConnection;
import model.NetworkConnection.Side;
import model.NetworkModel;
import model.NetworkNode;

public class AddConnectionDescriptor {
	private NetworkConnection connection;
	public Point pressPoint, dragPoint;
	
	public AddConnectionDescriptor() {
	}

	public Side contains(Point point, NetworkNode node, FontMetrics fm, boolean press) {
		int w = fm.stringWidth(node.getName());
		int width = ((int)(w / 2 * 1.2) / 10 + 1) * 10;
		int height = ((int)(w / 2 * .5) / 10 + 1) * 10;
		
		if(Math.abs(point.x - node.getX()) <= 15 && Math.abs(point.y - (node.getY() - height)) <= 15) {
			if(press) {
				pressPoint = new Point((int)node.getX(), (int)node.getY() - height);
			}
			else {
				dragPoint = new Point((int)node.getX(), (int)node.getY() - height);
			}
			return Side.Top;
		}
		if(Math.abs(point.x - node.getX()) <= 15 && Math.abs(point.y - (node.getY() + height)) <= 15) {
			if(press) {
				pressPoint = new Point((int)node.getX(), (int)node.getY() + height);
			}
			else {
				dragPoint = new Point((int)node.getX(), (int)node.getY() + height);
			}
			return Side.Bottom;
		}
		if(Math.abs(point.y - node.getY()) <= 15 && Math.abs(point.x - (node.getX() - width)) <= 15) {
			if(press) {
				pressPoint = new Point((int)node.getX() - width, (int)node.getY());
			}
			else {
				dragPoint = new Point((int)node.getX() - width, (int)node.getY());
			}
			return Side.Left;
		}
		if(Math.abs(point.y - node.getY()) <= 15 && Math.abs(point.x - (node.getX() + width)) <= 15) {
			if(press) {
				pressPoint = new Point((int)node.getX() + width, (int)node.getY());
			}
			else {
				dragPoint = new Point((int)node.getX() + width, (int)node.getY());
			}
			
			return Side.Right;
		}
		
		return null;
	}

	public void setPressPoint(Point point, NetworkModel model, FontMetrics fm) {
		for(int i = model.nNodes() - 1; i >= 0; i--) {
			Side side = contains(point, model.getNode(i), fm, true);
			if(side != null) {
				connection = new NetworkConnection(model.getNode(i), side);
				return;
			}
		}
	}
	
	public void setDragPoint(Point point, NetworkModel model, FontMetrics fm) {
		if(connection == null) {
			return;
		}
		dragPoint = point;
		
		for(int i = model.nNodes() - 1; i >= 0; i--) {
			Side side = contains(point, model.getNode(i), fm, false);
			if(side != null) {
				return;
			}
		}
	}
	
	public void setReleasePoint(Point point, NetworkModel model, FontMetrics fm) {
		if(connection == null) {
			return;
		}
		for(int i = model.nNodes() - 1; i >= 0; i--) {
			Side side = contains(point, model.getNode(i), fm, false);
			if(side != null) {
				connection.node2 = model.getNode(i);
				connection.side2 = side;
				if(connection.node1 == connection.node2 && connection.side1 == connection.side2) {
					return;
				}
				model.addConnection(connection);
				return;
			}
		}
	}
	
	public void draw(Graphics2D g) {
		if(connection == null) {
			return;
		}
		g.setStroke(new BasicStroke(2));
		g.setColor(Paintbrush.seaFoam);
		g.drawRect(pressPoint.x - 2, pressPoint.y - 2, 5, 5);
		g.drawRect(dragPoint.x - 2, dragPoint.y - 2, 5, 5);
		g.setStroke(new BasicStroke(1));
		g.setColor(Paintbrush.navy);
		g.draw(new Line2D.Double(pressPoint.x, pressPoint.y, dragPoint.x, dragPoint.y));
	}
}
